<template>
    <div class="edu-page-warp">
        <div class="edu-page-title">角色列表</div>
        <el-row :gutter="0" class="bg-white pd-20px" style="min-height: 540px">
            <el-col>
                <el-row :gutter="20" style="border-bottom: 1px solid #d2d4d6;">
                    <el-col :span="6">
                        <el-input
                            v-model="queryForm.roleName"
                            placeholder="角色名称"
                            prefix-icon="el-icon-search"
                            @keyup.enter.native="queryRoles(true)"
                            clearable>
                        </el-input>
                    </el-col>
                    <el-col :span="2">
                        <el-button @click="queryRoles(true)">{{$t('message.filter')}}</el-button>
                    </el-col>
                    <el-col :span="10">
                        <div class="empty-box"></div>
                    </el-col>
                    <el-col :span="6">
                        <div class="float-right" style="margin-top: 6px;">
                            <el-button @click="popCreateRole" v-premit="'create_role'">新增角色</el-button>
                        </div>
                    </el-col>
                </el-row>
                <el-row :gutter="0" class="no-margin">
                    <el-col>
                        <el-table :data="list" @selection-change="handleRolesSelectChange" stripe>
                            <el-table-column type="selection" width="42"></el-table-column>
                            <el-table-column label="角色名称">
                                <template slot-scope="scope">
                                    <span :title="scope.row.roleName">{{scope.row.roleName}}</span>
                                </template>
                            </el-table-column>
                            <el-table-column label="创建人">
                                <template slot-scope="scope">{{scope.row.createBy}}</template>
                            </el-table-column>
                            <el-table-column label="创建时间">
                                <template slot-scope="scope">{{getDateStr(scope.row.createDate)}}</template>
                            </el-table-column>
                            <el-table-column label="备注">
                                <template slot-scope="scope">
                                    <span :title="scope.row.description">{{scope.row.description}}</span>
                                </template>
                            </el-table-column>
                            <el-table-column label="操作" width="180">
                                <template slot-scope="scope">
                                    <el-button
                                        type="text"
                                        @click="_showAuthorityDialog(scope.row.roleId)"
                                        v-premit="'authorize'"
                                    >授权</el-button>
                                    <el-button
                                        type="text"
                                        @click="relationWithGroup(scope.row.roleId)"
                                        v-premit="'bind_role_to_group'"
                                    >管理组</el-button>
                                    <el-button
                                        type="text"
                                        @click="showEditRoleBox(scope.row)"
                                        v-premit="'edit_role'"
                                    >编辑</el-button>
                                    <el-button
                                        type="text"
                                        @click="deleteRole(scope.row.roleId)"
                                        v-premit="'delete_role'"
                                    >删除</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </el-col>
                </el-row>
                <el-row :gutter="0">
                    <el-col>
                        <el-pagination
                            @size-change="handleSizeChange"
                            @current-change="handlePageNumChange"
                            :current-page="queryForm.pageNum_"
                            :page-sizes="[20,50,100,500,1000]"
                            :page-size="queryForm.pageSize_"
                            layout="total, sizes, prev, pager, next, jumper"
                            :total="queryForm.total"
                            style="float: right;margin:10px 60px 0 0;"
                        ></el-pagination>
                    </el-col>
                </el-row>
            </el-col>
        </el-row>

        <edu-dialog 
            title="新增角色"
            width="600px"
            :visible.sync="showCreateRoleDialog"
            @close="showCreateRoleDialog = false"
            @confirm="createRole">
            <el-form
                :model="createRoleForm"
                ref="createRoleForm"
                label-width="95px"
                class="pd-20px"
                :rules="rules">
                <el-row>
                    <el-form-item label="角色名称" prop="roleName">
                        <el-input v-model="createRoleForm.roleName"></el-input>
                    </el-form-item>
                </el-row>
                <el-row>
                    <el-form-item label="创建人">
                        <el-input v-model="createRoleForm.createBy" disabled></el-input>
                    </el-form-item>
                </el-row>
                <el-row>
                    <el-form-item label="备注" prop="description">
                        <el-input type="textarea" v-model="createRoleForm.description"></el-input>
                    </el-form-item>
                </el-row>
            </el-form>
            <!-- <span slot="footer">
                <el-button @click="showCreateRoleDialog = false">{{$t('message.cancel')}}</el-button>
                <el-button type="primary" @click="createRole">保存</el-button>
            </span> -->
        </edu-dialog>

        <edu-dialog 
            title="编辑" 
            width="600px"
            :visible.sync="showEditRoleDialog"
            @close="showEditRoleDialog = false"
            @confirm="editRole">
            <el-form
                :model="editRoleForm"
                ref="editRoleForm"
                label-width="95px"
                class="pd-20px"
                :rules="rules">
                <el-row>
                    <el-form-item label="角色名称" prop="roleName">
                        <el-input v-model="editRoleForm.roleName"></el-input>
                    </el-form-item>
                </el-row>
                <el-row :span="12">
                    <el-form-item label="创建人">
                        <el-input v-model="editRoleForm.createBy" readonly></el-input>
                    </el-form-item>
                </el-row>
                <el-row>
                    <el-form-item label="备注" prop="description">
                        <el-input type="textarea" v-model="editRoleForm.description"></el-input>
                    </el-form-item>
                </el-row>
            </el-form>
            <!-- <span slot="footer">
                <el-button @click="showEditRoleDialog = false">{{$t('message.cancel')}}</el-button>
                <el-button type="primary" @click="editRole">保存</el-button>
            </span> -->
        </edu-dialog>

        <edu-dialog
            title="授权"
            width="1000px"
            :visible.sync="showAuthorityDialog"
            style="min-width:540px;"
            class="roleList-dialog"
            :showCancelBtn=false
            :showConfirmBtn=false>
            <div v-loading="authorityLoading">
                <el-row class="authority-actionBar">
                    <el-radio-group v-model="radioTypeOpt.value" size="small">
                        <el-radio-button v-for="(type,index) in radioTypeOpt.data" :key="index" :label="type.value">
                            {{ type.name }}
                        </el-radio-button>
                    </el-radio-group>
                    <div class="float-right">
                        <!-- 清空 -->
                        <!-- <el-button @click="clearAddedAuthority">{{ $t('arrangement.profMatching.matchClear') }}</el-button> -->
                    </div>
                </el-row>
                <div class="margin-top-16 auth-root-box">
                    <edu-transfer
                        leftTitle="所有权限"
                        rightTitle="已添加权限"
                        ref="allDeptsTree"
                        leftChecked="true"
                        rightChecked="true"
                        :class="clearState ? 'hidedenCheck' : ''"
                        :rightEduTransfer="true"
                        :leftTransferData="leftTransferData[radioTypeOpt.value - 1]"
                        :rightTransferData="rightTransferData"
                        v-on="{addNodesToRight:pickAuthorities,delNodesFromRight:unpickAuthorities}"
                    />
                </div>
            </div>
        </edu-dialog>

        <edu-dialog 
            title="管理组" 
            width="1000px" 
            :visible.sync="showGroupsDialog"
            :showCancelBtn=false
            :showConfirmBtn=false>
            <div class="auth-root-box">
                <section class="tree-box">
                    <p>所有组</p>
                    <div>
                        <el-checkbox-group v-model="pickedGroupsOfAll">
                            <el-checkbox
                                v-for="(item, index) in groups"
                                :label="item.label"
                                :key="index"
                            ></el-checkbox>
                        </el-checkbox-group>
                    </div>
                </section>
                <section class="transfer-box">
                    <center>
                        <el-button circle class="el-icon-d-arrow-right" @click="pickGroups"></el-button>
                    </center>
                    <br />
                    <center>
                        <el-button circle class="el-icon-d-arrow-left" @click="unpickGroups"></el-button>
                    </center>
                </section>
                <section class="tree-box">
                    <p>已绑定用户组</p>
                    <div>
                        <el-checkbox-group v-model="pickedGroupsOfBinded">
                            <el-checkbox
                                v-for="(item, index) in pickedGroups"
                                :label="item.label"
                                :key="index"
                            ></el-checkbox>
                        </el-checkbox-group>
                    </div>
                </section>
            </div>
        </edu-dialog>
    </div>
</template>
<script>
import {
    getRoles,
    addrole,
    getAuthorities,
    getAuthOrDeptRelListByRoleId,
    batchAddAuthOrDeptToRoleRel,
    _deleteRole,
    getGroupListByRoleId,
    getGroupListNotInRoleId,
    batchDelAuthOrDeptToRoleRel,
    batchAddGroupRelByRoleId,
    batchAddRoleGroupRel,
    batchDelGroupRelByRoleId,
    updateRole
} from "common/src/api/user";
import { findAllDeptList, findDeptList } from "common/src/api/user";
import EduTransfer from "common/src/components/common/EduTransfer";
import UTILS from "common/src/utils/utils";
export default {
    name: "RoleList",
    data() {
        var validateName = (rule, value, callback) => {
            var regex = /^[\w\d\s\S\u4e00-\u9fa5]{4,100}$/;
            if (regex.test(value)) {
                callback();
            } else {
                callback(
                    new Error(
                        UTILS.i18nReplace(this.$t("system.errorTipInfo"), {
                            minLength: 4,
                            maxLength: 100
                        })
                    )
                );
            }
        };
        var validateDesc = (rule, value, callback) => {
            var regex = /^.{0,120}$/;
            if (regex.test(value)) {
                callback();
            } else {
                callback(new Error("备注信息不能超过120个字符."));
            }
        };
        return {
            leftTransferData: "",
            rightTransferData: "",
            chooseAllAuth: false,
            chooseAllPickedAuth: false,
            chooseAllGroup: false,
            chooseAllPickedGroup: false,
            showCreateRoleDialog: false,
            showAuthorityDialog: false,
            showGroupsDialog: false,
            showEditRoleDialog: false,
            clearState: false,
            authorityLoading: false,
            queryForm: {
                roleName: "",
                pageNum_: 1,
                total: 0,
                pageSize_: 20
            },
            createRoleForm: {
                roleName: "",
                createBy: "",
                description: ""
            },
            editRoleForm: {},
            list: [],
            allAuthorities: [],
            defaultProps: {
                children: "children",
                label: "authNameCh"
            },
            pickedRelProps: {
                children: "children",
                label: "valueName"
            },
            pickedAuthorities: [],
            curPickedAuthorities: [],
            allAuthorities_origin: [],
            pickedAuthorities_origin: [],

            leftCheckedGroups: [],
            rightCheckedGroups: [],
            isChooseAllGroup: true,
            chooseAllGroup: false,
            curRoleId: "",
            pickedroles: [],
            groups: [],
            pickedGroups: [],
            pickedGroupsOfAll: [],
            isIndeterminate: true,
            pickedGroupsOfBinded: [],
            curPickedAuthoritiesAtRight: [],
            allPickedDepts: [],
            rules: {
                roleName: [
                    {
                        validator: validateName,
                        trigger: "blur"
                    }
                ],
                description: [
                    {
                        validator: validateDesc,
                        trigger: "blur"
                    }
                ]
            },
            radioTypeOpt: {
                value: 1,
                data: [
                    {
                        name: "管理员菜单",
                        value: 1
                    },
                    {
                        name: "教师菜单",
                        value: 2
                    },
                    {
                        name: "学生菜单",
                        value: 3
                    }
                ]
            }
        };
    },
    components: { EduTransfer },
    created() {},
    mounted() {
        this.queryRoles();
    },
    watch: {
        "radioTypeOpt.value" (val) {
            this.getAuthoritiesPicked(this.curRoleId)
        }
    },
    methods: {
        async getRoles(queryForm) {
            try {
                let resp = await getRoles(queryForm);
                if (resp && resp.data) {
                    this.list = resp.data.list;
                    this.queryForm.total = resp.data.total_;
                }
            } catch (error) {
                console.log(error)
            }
        },
        async addrole(queryForm) {
            try {
                let resp = await addrole(queryForm);
                if (resp && resp.code == 200) {
                    this.$message({
                        type: 'success',
                        message: '添加成功'
                    });
                    this.showCreateRoleDialog = false;
                    this.$refs.createRoleForm.resetFields();
                    this.queryRoles(true);
                } else if (resp && resp.code == 300) {
                    this.$message({
                        type: 'error',
                        message: '重复添加'
                    });
                } else {
                    this.$message({
                        type: 'error',
                        message: '添加失败, 请重新再试'
                    });
                }
            } catch (error) {
                console.log(error)
            }
        },
        async getAllAuthority() {
            try {
                const resp = await Promise.all([
                    getAuthorities({ roleType: 1 }),
                    getAuthorities({ roleType: 2 }),
                    getAuthorities({ roleType: 3 })
                ])
                if (_.isArray(resp)) {
                    this.leftTransferData = [];
                    resp.forEach(item => {
                        if (item.code === 200 && item.data) {
                            this.leftTransferData.push(JSON.stringify(item.data));
                        }
                    });
                    this.authorityLoading = false;
                }
            } catch (error) {
                console.log(error)
                this.authorityLoading = false;
            }
        },
        async getAuthOrDeptRelListByRoleId(queryForm) {
            try {
                let resp = await getAuthOrDeptRelListByRoleId(queryForm);
                if (resp && resp.data && resp.code == 200 ) {
                    // 已选择权限与所有权限返回的接口字段不同，进行转换，edu-transfer需要统一字段
                    let rightTransferData = resp.data.map(item => {
                        return {
                            parentAuthId: item.parentId,
                            authNameCh: item.valueName,
                            authNameEn: item.valueNameEn,
                            authId: item.valueId,
                            roleId: item.roleId
                        };
                    });
                    this.rightTransferData = JSON.stringify(
                        rightTransferData
                    );
                    this.clearState = false;
                } else {
                    this.setDataFormatErrMsg();
                }
            } catch (error) {
                console.log(error)
            }
        },
        async batchAddAuthOrDeptToRoleRel(queryForm) {
            try {
                let resp = await batchAddAuthOrDeptToRoleRel(queryForm);
                if (resp && resp.code == 200) {
                    this.$message({
                        type: 'success',
                        message: '添加成功'
                    });
                    if (queryForm.type == 1) {
                        this.getAllAuthority();
                        this.getAuthoritiesPicked(this.curRoleId);
                    }
                } else if (resp && resp.code == 300) {
                    this.$message({
                        type: 'warning',
                        message: '重复添加'
                    });
                } else {
                    this.setDataFormatErrMsg();
                }
            } catch (error) {
                console.log(error)
            }
        },
        async getGroupListByRoleId(queryForm) {
            try {
                let resp = await getGroupListByRoleId(queryForm);
                if (resp && resp.code == 200) {
                    this.pickedGroups = this.getMap(resp.data);
                } else {
                    this.setDataFormatErrMsg();
                }
            } catch (error) {
                console.log(error)
            }
        },
        async getGroupListNotInRoleId(queryForm) {
            try {
                let resp = await getGroupListNotInRoleId(queryForm);
                if (resp && resp.code == 200) {
                    this.groups = this.getMap(resp.data);
                } else {
                    this.setDataFormatErrMsg();
                }
            } catch (error) {
                console.log(error)
            }
        },
        async batchDelAuthOrDeptToRoleRel(queryForm) {
            try {
                let resp = await batchDelAuthOrDeptToRoleRel(queryForm);
                if (resp && resp.code == 200) {
                    this.$message({
                        type: "success",
                        message: "删除权限成功"
                    });
                    if (queryForm.type == 1) {
                        this.getAllAuthority();
                        this.getAuthoritiesPicked(this.curRoleId);
                    }
                } else {
                    this.setDataFormatErrMsg();
                }
            } catch (error) {
                console.log(error)
            }
        },
        async batchAddGroupRelByRoleId(queryForm) {
            try {
                let resp = await batchAddGroupRelByRoleId(queryForm);
                if (resp && resp.code == 200) {
                    this.$message({
                        type: 'success',
                        message: '绑定关系成功'
                    });
                    this.queryRelatedGroups();
                } else {
                    this.$message({
                        type: 'error',
                        message: '操作失败'
                    });
                }
            } catch (error) {
                console.log(error)
            }
        },
        async batchDelGroupRelByRoleId(queryForm) {
            try {
                let resp = await batchDelGroupRelByRoleId(queryForm);
                if (resp && resp.code == 200) {
                    this.$message({
                        type: 'success',
                        message: '删除绑定关系成功'
                    });
                    this.queryRelatedGroups();
                }
            } catch (error) {
                console.log(error)
            }
        },
        async updateRole(queryForm) {
            try {
                let resp = await updateRole(queryForm);
                if (resp && resp.code == 200) {
                    this.$message({
                        type: 'success',
                        message: this.$t('common.tips.addSuccess')
                    });
                    this.showEditRoleDialog = false;
                    this.$refs.editRoleForm.resetFields();
                    this.queryRoles();
                } else {
                    this.setDataFormatErrMsg();
                }
            } catch (error) {
                console.log(error)
            }
        },
        setDataFormatErrMsg(msg) {
            msg = msg ? msg : 'The data returned is malformed'
            this.$message({
                type: 'error',
                message: msg
            });
        },
        popCreateRole() {
            this.showCreateRoleDialog = true;
            this.createRoleForm.createBy = this.$store.state.session.user.name;
        },
        handlePageNumChange(val) {
            this.queryForm.pageNum_ = val;
            this.queryRoles();
        },
        handleSizeChange(val) {
            this.queryForm.pageSize_ = val;
            this.queryRoles();
        },

        findkeys(name, list) {
            let x = "";
            list.forEach((item, index) => {
                if (name == item.label) {
                    x = item.key;
                    return false;
                }
            });
            return x;
        },
        unpickGroups() {
            if (this.pickedGroupsOfBinded.length == 0) {
                this.$message({
                    type: "warning",
                    message: "请至少选择一个用户组."
                });
                return;
            }
            let that = this;
            let _groupList = this.pickedGroupsOfBinded.map((item, index) => {
                return { groupId: that.findkeys(item, this.pickedGroups) };
            });
            let data = {
                roleId: this.curRoleId,
                groupList: _groupList
            };
            this.batchDelGroupRelByRoleId(data);
        },
        pickGroups() {
            if (this.pickedGroupsOfAll.length == 0) {
                this.$message({
                    type: "warning",
                    message: "请至少选择一个用户组."
                });
                return;
            }
            let that = this;
            let _groupList = this.pickedGroupsOfAll.map((item, index) => {
                return { groupId: that.findkeys(item, this.groups) };
            });
            let data = {
                roleId: this.curRoleId,
                groupList: _groupList
            };
            this.batchAddGroupRelByRoleId(data);
        },
        getDateStr(d) {
            if (d != null && d != undefined && d != 0)
                return new Date(d).toLocaleDateString();
            else return "";
        },
        handleRolesSelectChange(items) {
            this.pickedroles = items;
        },
        createRole() {
            this.$refs.createRoleForm.validate(valid => {
                if (valid) {
                    this.addrole(this.createRoleForm);
                }
            });
        },

        editRole() {
            this.$refs.editRoleForm.validate(valid => {
                if (valid) {
                    this.updateRole(this.editRoleForm);
                }
            });
        },
        queryRoles(reset) {
            if (reset) {
                this.queryForm.pageNum_ = 1;
                this.queryForm.total = 0;
            }
            this.getRoles(this.queryForm);
        },
        _showAuthorityDialog(roleId) {
            this.showAuthorityDialog = true;
            this.authorityLoading = true;
            this.getAllAuthority();
            this.curRoleId = roleId;
            if (roleId) this.getAuthoritiesPicked(roleId);
        },
        getAuthoritiesPicked(roleId) {
            this.getAuthOrDeptRelListByRoleId(`roleId=${roleId}&type=1&roleType=${this.radioTypeOpt.value}`);
        },
        addAuthorityToRole() {},
        relationWithGroup(roleId) {
            this.showGroupsDialog = true;
            this.curRoleId = roleId;
            this.queryRelatedGroups();
        },
        queryRelatedGroups() {
            let query = "roleId=" + this.curRoleId;
            this.getGroupListByRoleId(query);
            this.getGroupListNotInRoleId(query);
        },
        getMap(list) {
            return list.map((item, index) => {
                return {
                    label: item.groupName,
                    key: item.groupId
                };
            });
        },
        writeRelatedGroupRel() {},
        showEditRoleBox(role) {
            this.showEditRoleDialog = true;
            this.editRoleForm = JSON.parse(JSON.stringify(role));
        },
        deleteRole(_roleId) {
            let _that = this;
            this.$confirm("确定要删除该记录吗?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning"
            })
                .then(_ => {
                    doDelete(_that);
                })
                .catch(error => {
                    that.$message({
                        type: "error",
                        message: "操作失败"
                    });
                });
            function doDelete(that) {
                _deleteRole("roleId=" + _roleId).then(res => {
                    if (res.code == 200) {
                        that.$message({
                            type: "success",
                            message: "删除成功"
                        });
                        that.queryRoles(true);
                    } else if (res.code == 300)
                        that.$message({
                            type: "warning",
                            message: "该角色已关联用户组, 不能删除."
                        });
                    throw res.code;
                });
            }
        },
        deleteRoles() {},
        handleLeftTree(picked) {
            this.curPickedAuthorities = picked;
        },
        handleRightTree(picked) {
            this.curPickedAuthoritiesAtRight = picked;
        },
        pickAuthorities({ resultWithParent }) {
            let data = {
                roleId: this.curRoleId,
                roleType: this.radioTypeOpt.value,
                type: 1,
                auth: resultWithParent
            };
            this.writeAuthsOrDeptsRelForRole(data);
        },
        writeAuthsOrDeptsRelForRole(data) {
            this.batchAddAuthOrDeptToRoleRel(data);
        },
        getAuthorityIdFromNode(parentAuthId, originList) {
            var cur = parentAuthId;
            var auths = [];
            while (cur > 0) {
                originList.forEach((item, index) => {
                    if (item.authId == cur) {
                        auths.push(item.authId);
                        cur = item.parentAuthId;
                    }
                });
            }
            return auths;
        },
        unpickAuthorities({ result }) {
            let data = {
                roleId: this.curRoleId,
                roleType: this.radioTypeOpt.value,
                type: 1,
                auth: result
            };
            this.rollbackAuthsOrDeptsRelForRole(data);
        },
        rollbackAuthsOrDeptsRelForRole(data) {
            this.batchDelAuthOrDeptToRoleRel(data);
        },
        handleCheckedGroupsChange(val) {
            let checkedCount = val.length;
            this.chooseAllGroup = checkedCount === this.allGroups.length;
            this.isChooseAllGroup =
                checkedCount > 0 && checkedCount < this.allGroups.length;
        },
        handleCheckAllChange(val) {
            this.leftCheckedGroups = val ? this.allGroups : [];
            this.isChooseAllGroup = false;
        },
        clearAddedAuthority() {
            // 清空复选框会打勾
            this.clearState = true;
            this.$refs.allDeptsTree.handleRightCheckAllChange(true);
            this.$refs.allDeptsTree.removeNodes();
        }
    }
};
</script>
<style lang="scss" scoped>
.auth-root-box {
    padding: 0;
    margin: 0;
    min-width: 540px;
    height: 360px;
    section {
        height: 100%;
        float: left;
    }
    section.tree-box {
        width: 46%;
        border: 1px solid #e5e5e5;
        border-radius: 2px;
        p {
            margin: 0;
            padding: 0;
            height: 36px;
            line-height: 36px;
            font-weight: 600;
            border-bottom: 1px solid #e5e5e5;
            padding-left: 12px;
            background: #eee;
        }
        div {
            width: 100%;
            height: calc(100% - 20px);
            overflow: auto;
        }
        .el-tree {
            padding: 5px;
        }
    }
    section.transfer-box {
        width: 8%;
        padding-top: 120px;
        .el-button {
            margin-bottom: 10px;
        }
    }
}
.el-checkbox-group {
    .el-checkbox {
        margin: 8px 12px;
        display: block;
    }
}
.self-check {
    display: block;
    margin: 8px 20px;
}
.authority-actionBar {
    margin-bottom: 16px;
    width: 98%;
}
</style>